/*
 *  WorkoutPrograms.h
 *  Workout
 *
 *  Created by Matt Krugman on 4/24/10.
 *
 */

#ifndef _WorkoutPrograms_H_
#define _WorkoutPrograms_H_

#define WORKOUTPROGRAM_MAX_WORKOUTS 150

#define WORKOUTPROGRAM_CYCLES 3

#define SUNDAY		(1 << 0)
#define MONDAY		(1 << 1)
#define TUESDAY		(1 << 2)
#define WEDNESDAY (1 << 3)
#define THURSDAY	(1 << 4)
#define FRIDAY		(1 << 5)
#define SATURDAY	(1 << 6)


#include <stdio.h>
#include "Workout.h"
#include "CoreWorkouts.h"
#include "OlympicWorkouts.h"

typedef void (*generateWorkoutProc)(int *pDate, const int week, int *pBasePercent, int *pDeltaPercent, int *pDayIncrements, int incrementLength, void* vpRef);

///////////////////////////////////////////////////////////////////////////

class WorkoutProgram : public ExerciseGoals {
public:
  
  WorkoutProgram(const char * title, 
		 int startDate,
		 generateWorkoutProc gwProc,
		 int weeks /* = 12 */);
	
	WorkoutProgram(WorkoutProgram* wp) : 
	  m_nWeeks(12),
	  m_startDate(20100101),
	  m_nW(0),
	  m_nCycles(3), 
	  m_daysofweek(0),
	  m_basePercent(60),
	  m_percentProc(percentSawtooth),
	  m_gwProc(NULL) { *this = wp; };
  
  
  ~WorkoutProgram(void) {};
  
  virtual void GenerateSession(void);
	void GenerateSession(generateWorkoutProc gwProc);
	
  const char * GetTitle(OutputType t, FILE *pFile = NULL);
  
  void GetWorkoutProgramDescription(OutputType t, FILE *pFile = NULL);
  inline void SetWorkoutProgramDescription(const char * d) {
    sprintf(m_description, "%s", d);
  };
	int GetWorkoutStartDate(void) { return m_startDate; };
	int GetWorkoutProgramNumCycles(void) { return m_nCycles; };
	int GetWorkoutProgramNumWeeks(void) { return m_nWeeks; };
	int GetWorkoutProgramDaysOfWeek(void) { return m_daysofweek; };
	int GetWorkoutLastIndex(void) { return m_nW; };
	
	inline void SetCycles(int c) { m_nCycles = c; };
	inline void SetPercentProc(percentProc pP) { m_percentProc = pP; };
	inline void SetWorkoutDaysFlag(char d) { m_daysofweek = d; }
	inline void SetBasePercent(int p) { m_basePercent = p; };
	inline void IncrementWorkoutCount(void) { m_nW++; };

  void Output(OutputType t);
	
	Workout m_workouts[WORKOUTPROGRAM_MAX_WORKOUTS];
	
	percentProc m_percentProc;
	
	bool AlternateSquat(Workout *pW, 
											bool *pBS, 
											setType s, 
											bool bOptional = false, 
											weightCalcProc calcProc = calcSine,
											float fBaseCalcPercent = 0.6f);
  
  bool AddCombination(Workout *pW, 
											int *pIndex,
											setType s,
											bool bOptional = false,
											weightCalcProc calcProc = calcSine);
  
  bool RandomCore(Workout *pW, 
									setType s,
									bool bOptional = false,
									weightCalcProc calcProc = calcSine);	
	
	bool RandomPress(Workout *pW, 
									 setType s,
									 bool bOptional = false,
									 weightCalcProc calcProc = calcSine,
									 float adjPercent = 1.0f);
	
	bool RandomSnatch(Workout *pW, 
										setType s,
										bool bOptional = false,
										weightCalcProc calcProc = calcSine);
	
	bool RandomClean(Workout *pW, 
									 setType s,
									 bool bOptional = false,
									 weightCalcProc calcProc = calcSine);	
	
	bool RandomJerk(Workout *pW, 
									setType s,
									bool bOptional = false,
									weightCalcProc calcProc = calcSine);
	
	bool RandomPull(Workout *pW, 
										setType s,
										bool bOptional = false,
										weightCalcProc calcProc = calcSine,
									float adjPercent = 1.0f);
  
protected:
  
  int m_nWeeks;
  char m_title[32];
  char m_description[32];
  int m_startDate;
  int m_nW;
	int m_nCycles;
	char m_daysofweek;
	int m_basePercent;
	
	
	generateWorkoutProc m_gwProc;
	
private: 
  
  
  
};

///////////////////////////////////////////////////////////////////////////



#endif

